package cn.drenal.capcap.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.drenal.capcap.entity.SysAdmin;
import cn.drenal.capcap.entity.SysAdminRole;
import cn.drenal.capcap.entity.SysPermission;
import cn.drenal.capcap.entity.SysRolePermission;
import cn.drenal.capcap.entity.dto.AdminLoginDTO;
import cn.drenal.capcap.entity.vo.AdminLoginVO;
import cn.drenal.capcap.entity.vo.AdminUserInfoVO;
import cn.drenal.capcap.exception.BizException;
import cn.drenal.capcap.mapper.SysAdminMapper;
import cn.drenal.capcap.mapper.SysAdminRoleMapper;
import cn.drenal.capcap.mapper.SysPermissionMapper;
import cn.drenal.capcap.mapper.SysRolePermissionMapper;
import cn.drenal.capcap.service.AdminLoginService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import cn.dev33.satoken.secure.SaSecureUtil;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 后台管理登录服务实现
 */
@Service
@RequiredArgsConstructor
public class AdminLoginServiceImpl implements AdminLoginService {

    private final SysAdminMapper sysAdminMapper;
    private final SysAdminRoleMapper sysAdminRoleMapper;
    private final SysRolePermissionMapper sysRolePermissionMapper;
    private final SysPermissionMapper sysPermissionMapper;

    @Override
    public AdminLoginVO login(AdminLoginDTO loginDTO) {
        // 查询用户
        SysAdmin admin = sysAdminMapper.selectOne(
                new LambdaQueryWrapper<SysAdmin>()
                        .eq(SysAdmin::getUsername, loginDTO.getUsername())
        );

        // 验证用户是否存在
        if (admin == null) {
            throw new BizException("用户名或密码错误");
        }

        // 验证密码
        if (!admin.getPassword().equals(SaSecureUtil.md5(loginDTO.getPassword()))) {
            throw new BizException("用户名或密码错误");
        }

        // 验证用户状态
        if (admin.getStatus() != 1) {
            throw new BizException("账号已被禁用");
        }

        // 更新最后登录时间
        admin.setLastLoginTime(LocalDateTime.now());
        sysAdminMapper.updateById(admin);

        // 生成token
        StpUtil.login(admin.getId());
        String token = StpUtil.getTokenValue();

        // 构建返回结果
        AdminLoginVO loginVO = new AdminLoginVO();
        BeanUtils.copyProperties(admin, loginVO);
        loginVO.setToken(token);

        return loginVO;
    }

    @Override
    public AdminUserInfoVO getLoginUserInfo(Long userId) {
        SysAdmin admin = sysAdminMapper.selectById(userId);
        AdminUserInfoVO vo = new AdminUserInfoVO();
        vo.setIsLogin(true);
        vo.setUsername(admin.getUsername());
        vo.setId(admin.getId());
        vo.setNickname(admin.getNickname());
        vo.setAvatar(admin.getAvatar());
        return vo;
    }

    @Override
    public void logout() {
        StpUtil.logout();
    }

    @Override
    public List<String> getPermissions(Long userId) {
        // 1. 查询用户角色关联
        List<Long> roleIds = sysAdminRoleMapper.selectList(
                new LambdaQueryWrapper<SysAdminRole>()
                        .eq(SysAdminRole::getUserId, userId)
        ).stream().map(SysAdminRole::getRoleId).collect(Collectors.toList());
        
        if (roleIds.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 查询角色权限关联获取permissionId列表
        List<Long> permissionIds = sysRolePermissionMapper.selectList(
                new LambdaQueryWrapper<SysRolePermission>()
                        .in(SysRolePermission::getRoleId, roleIds)
        ).stream().map(SysRolePermission::getPermissionId).collect(Collectors.toList());
        
        if (permissionIds.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 3. 通过permissionId查询权限详细信息
        return sysPermissionMapper.selectList(
                new LambdaQueryWrapper<SysPermission>()
                        .in(SysPermission::getId, permissionIds)
        ).stream().map(SysPermission::getPermission).collect(Collectors.toList());
    }
}